package WebGamble;

import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class PCEggsStatic28New extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	static String BaseURL = "http://www.pceggs.com/play/pg28Insert.aspx?LID=";
	static Random rand = new Random();

	static private HttpResponse httpResponse;
	final static HttpParams httpParams = new BasicHttpParams();
	final static HttpParams altHttpParams = new BasicHttpParams();
	static private DefaultHttpClient httpClient;

	static public class showImg extends JPanel {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		JLabel jl = null;
		ImageIcon img = null;

		public showImg(InputStream bmpFile) throws IOException {
			img = new ImageIcon(ImageIO.read(bmpFile));
			jl = new JLabel(img);
			this.setLayout(new BorderLayout());
			this.add(jl, BorderLayout.CENTER);
		}
	}

	static public int GCD(int numA, int numB) {
		int gcd = 1;
		for (int k = 1; k <= numA && k <= numB; k++)
			if (numA % k == 0 && numB % k == 0)
				gcd = k;
		return gcd;
	}

	static public double min(double[] valList) {
		double val;
		val = valList[0];
		for (double value : valList) {
			if (value < val)
				val = value;
		}
		return val;
	}

	static public int MinLoc(double[] valList) {
		double val;
		val = valList[0];
		int i = 0, loc = 0;
		for (double value : valList) {
			if (value < val) {
				val = value;
				loc = i;
			}
			i++;
		}
		return loc;
	}

	static public double max(double[] valList) {
		double val;
		val = valList[0];
		for (double value : valList) {
			if (value > val)
				val = value;
		}
		return val;
	}

	static public int sum(int[] valList) {
		int val = 0;
		for (int value : valList)
			val += value;
		return val;
	}

	static public double sum(double[] valList) {
		double val = 0;
		for (double value : valList)
			val += value;
		return val;
	}

	static public double score1(double[] oddsList, int[] distribution) {
		double[] score = new double[28];
		double count = 0;
		double s = sum(distribution);
		for (int i = 0; i < 28; i++) {
			score[i] = oddsList[i] * distribution[i] - s;
			if (score[i] < 0)
				count += originDist[i];
		}
		return min(score) - count * 2;
	}

//	static public int[] originDist = { 1, 3, 6, 10, 15, 21, 28, 72, 90, 110,
//			126, 138, 146, 150, 150, 146, 138, 126, 110, 90, 72, 28, 21, 15,
//			10, 6, 3, 1 };
	 static public int[] originDist = {1, 3, 6, 10, 15, 21, 28, 36, 45, 56,
	 63, 67, 71, 77, 77, 71, 67, 63, 56, 45, 36, 28, 21, 15, 10, 6, 3, 1};
	static public double total = sum(originDist);

	static public double score2(double[] oddsList, int[] distribution) {
		double[] score = new double[28];
		double count = 0;
		double s = sum(distribution);
		for (int i = 0; i < 28; i++) {
			score[i] = (oddsList[i] * distribution[i] - s) * originDist[i];
			if (score[i] < 0)
				count += 1;
		}
		return sum(score) / total - count;
	}

	static public double score3(double[] oddsList, int[] distribution) {
		double[] score = new double[28];
		double s = sum(distribution);
		for (int i = 0; i < 28; i++) {
			score[i] = (oddsList[i] * distribution[i] - s) * originDist[i];
		}
		return sum(score) / total;
	}

	static public int[] baseDist = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2 };

	static public int showStatus(double[] oddsList, int[] distribution,
			int idx, boolean showFlag) {
		double[] score = new double[28];
		int s = sum(distribution);
		int count = 0;
		if (showFlag) {
			System.out.println(idx + "th step:");
			for (int i = 0; i < 28; i++) {
				System.out.printf("%d: %03d, ", i, distribution[i]);
			}
			System.out.println();
		}
		for (int i = 0; i < 28; i++) {
			score[i] = oddsList[i] * distribution[i] - s;
			if (score[i] < 0)
				count++;
			if (showFlag)
				System.out.printf("%d: %06f, ", i, score[i]);
		}
		if (showFlag) {
			System.out.println();
			System.out.println("Total negative: " + count);
			System.out.println("Min: " + min(score));
			System.out.println("Max: " + max(score));
			for (int i = 0; i < 28; i++)
				score[i] = score[i] * originDist[i];
			System.out.println("Avg: " + sum(score) / total);
			System.out.println("Num: " + s);
		}
		return count;
	}

	@SuppressWarnings("deprecation")
	public static void main(String[] args) throws ClientProtocolException,
			IOException, InterruptedException {
//		HttpConnectionParams.setConnectionTimeout(altHttpParams, 4000);
//		HttpConnectionParams.setSoTimeout(altHttpParams, 4000);
//		HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
//		HttpConnectionParams.setSoTimeout(httpParams, 30000);
		httpClient = new DefaultHttpClient();
		
		HttpGet httpGet;
		httpGet = new HttpGet("http://www.pceggs.com/nologin.aspx");
		httpResponse = httpClient.execute(httpGet);
		String loginHtml = EntityUtils.toString(httpResponse.getEntity(),
				"UTF-8");
		httpGet.releaseConnection();

		httpGet = new HttpGet(
				"http://www.pceggs.com/VerifyCode_Login.aspx");
		httpResponse = httpClient.execute(httpGet);
		JFrame pane = null;
		if(args.length > 0 && args[0].equalsIgnoreCase("server")) {
			//save the verify code
			File file = new File("VerifyCode_28new.gif");
	        FileOutputStream outputStream = new FileOutputStream(file);
	        InputStream inputStream = httpResponse.getEntity().getContent();
	        byte b[] = new byte[1024];
	        int j;
	        while ((j = inputStream.read(b)) != -1) {
	            outputStream.write(b, 0, j);
	        }
	        outputStream.flush();
	        outputStream.close();
		}
		else {
			//show the verify code directly
			pane = new JFrame("Image Pane");
			pane.getContentPane().add(
					new showImg(httpResponse.getEntity().getContent()));
			pane.pack();
			pane.setVisible(true);
		}
		httpGet.releaseConnection();
		System.out.println("Please enter the verify code:");
		String VerifyCode;
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				System.in));
		VerifyCode = reader.readLine();

		Document loginDoc = Jsoup.parse(loginHtml);
		String loginURL = "http://www.pceggs.com/nologin.aspx";
		Elements loginInputs = loginDoc.select("input");
		
		HttpPost httpPost = new HttpPost("http://www.pceggs.com/LoginCheck.aspx?email=365064421@qq.com&pwd=qazxcdews123321&code=" + VerifyCode);
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("_isAjaxRequest", "true"));
		httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
		httpPost.addHeader("Connection", "keep-alive");
		httpPost.addHeader("Host", "www.pceggs.com");
		httpPost.addHeader("Referer", "http://www.pceggs.com/nologin.aspx");
		httpPost.addHeader("User-Agent",
				"Mozilla/5.0 (Windows NT 6.1; rv:18.0) Gecko/20100101 Firefox/18.0");
		httpResponse = httpClient.execute(httpPost);
		loginHtml = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
		System.out.println(loginHtml);
		if (loginHtml.compareTo("0") == 0) {
			System.out.println("Login success...");
		}
		else {
			System.out.println("Login failed...");
			System.exit(0);
		}
		httpPost.releaseConnection();
		
		httpPost = new HttpPost(loginURL);
		params = new ArrayList<NameValuePair>();
		for (Element input : loginInputs) {
			if (input.attr("type").compareToIgnoreCase("password") == 0) {
				input.attr("name", "txt_PWD");
				input.val("qazxcdews123321");
			} else if (input.attr("name").compareToIgnoreCase("email") == 0) {
				input.attr("name", "txt_UserName");
				input.val("gonerfile@126.com");
			} else if (input.attr("name").compareToIgnoreCase("txt_VerifyCode") == 0) {
				input.val(VerifyCode);
			} else if (input.attr("name").compareToIgnoreCase("FromUrl") == 0) {
				input.val("http://www.pceggs.com/");
			} else if (input.attr("name").compareToIgnoreCase("Login_Submit") == 0) {
				input.attr("name", "Login_Submit.x");
				input.val("32");
				params.add(new BasicNameValuePair(input.attr("name"), input
						.val()));
				System.out.println(input.attr("name") + ": " + input.val());
				input.attr("name", "Login_Submit.y");
				input.val("8");
				params.add(new BasicNameValuePair(input.attr("name"), input
						.val()));
				System.out.println(input.attr("name") + ": " + input.val());
				continue;
			}

			params.add(new BasicNameValuePair(input.attr("name"), input.val()));
			System.out.println(input.attr("name") + ": " + input.val());
		}
		httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
		httpPost.addHeader("Connection", "keep-alive");
		httpPost.addHeader("Host", "www.pceggs.com");
		httpPost.addHeader("Referer", "http://www.pceggs.com/nologin.aspx");
		httpPost.addHeader("User-Agent",
				"Mozilla/5.0 (Windows NT 6.1; rv:18.0) Gecko/20100101 Firefox/18.0");
		httpResponse = httpClient.execute(httpPost);
		loginHtml = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
//		System.out.println(loginHtml);
		httpPost.releaseConnection();
		
		if(args.length == 0)
			pane.dispose();

		float originTimes = 1;
		float altTimes;
        int money = 0, prevMoney = 0;
        float times = originTimes;
        int loseCount = 0;
        float lastTimes = 1;
        int sa = 10, sb = 17, except = 2;
        int[] distMask = {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1};
        float total = 476;
        boolean debug = false, watch = false;
        int warnFlag = 0;
        int loseLevel = 0;
        
		while (true) {
			httpGet = new HttpGet("http://www.pceggs.com/play/pc28.aspx");
			httpResponse = httpClient.execute(httpGet);
			String html = EntityUtils.toString(httpResponse.getEntity(),
					"UTF-8");

			httpGet.releaseConnection();
			Document document = Jsoup.parse(html);
			Elements elements = document.select("#panel tr:eq(5) td:eq(0)");
			if(elements.size() == 0)
				continue;
			int gambleId = Integer.parseInt(elements.get(0).text());
			elements = document.select("#panel tr:eq(5) td:eq(5) script");
			int lid = Integer
					.parseInt(elements.get(0).html().replaceAll(" ", "").substring(12, 18));
			String gambleURL = BaseURL + lid;
			int i;
			double[] oddsList = new double[28];
			String odds;

			long startT, endT;
			startT = System.currentTimeMillis();
			httpGet = new HttpGet("http://www.pceggs.com/play/pc28.aspx");
			httpResponse = httpClient.execute(httpGet);
			html = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
			httpGet.releaseConnection();
			document = Jsoup.parse(html);
			elements = document.select(".navigation_top .sheader_img_eggs .sheader_red:eq(0)");
			if(elements.get(1).text().replaceAll(",", "").isEmpty())
				continue;
			money = Integer.parseInt(elements.get(1).text().replaceAll(",", ""));

			System.out.println("Current Money: " + money);
			Pattern p = Pattern.compile("GetRTime\\([0-9]+\\);"), p1 = Pattern
					.compile("[0-9]+");
			Matcher m = p.matcher(html);
			m.find();
			html = m.group();
			m = p1.matcher(html);
			m.find();
			int timeout = Integer.parseInt(m.group());
			if (timeout <= 2) {
				System.out.println("Timeout...");
				Thread.sleep(5000);
				continue;
			}
			
			elements = document.select("#panel tr:gt(5) script");
			if(elements.size() == 0) {
				continue;
			}
			int[] history = new int[10];
			for (i = 0; i < history.length; i++) {
				history[i] = Integer.parseInt(elements.get(i * 4).html()
						.replaceAll(" ", "").substring(20, 22)) - 10;
				System.out.print(history[i] + ", ");
			}
			System.out.println();
			
			loseCount = 0;
			for (int val : history) {
				if (distMask[val] > 0) {
					break;
				} else {
					loseCount++;
				}
			}
			
			lastTimes = times;
			altTimes = 1;
			
			// update the total
			warnFlag = 0;
			if(loseCount == 0) {
				total = (float) Math.floor(money / 725);
			}
			else {
				warnFlag = 1;
			}
			System.out.println("Current total: " + total);
			
			if(loseCount > 0) {
				if(loseCount == 1) {
					altTimes = (float) 3;
				}
				else if(loseCount == 2) {
					altTimes = (float) 16;
				}
				else if(loseCount == 3) {
					altTimes = (float) 100;
					loseLevel++;
				}
				else if(loseCount == 4) {
					altTimes = (float) 600;
					loseLevel++;
				}
			}
			System.out.println("warnFlag: " + warnFlag);

            times = originTimes * altTimes;
            if(debug) {
            	times = 1;
			}
            if(loseCount > 0) {
            	System.err.println("Prediction wrong !!!");
            }
			if(warnFlag > 0 && loseCount > 0) {
				System.err.println("WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!!");
			}
			System.out.println("LoseCount: " + loseCount);
			System.out.println("Current times: " + times);
			prevMoney = money;

			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			System.out.println(df.format(new Date()));
			
			endT = System.currentTimeMillis();
			System.out.println("Time: " + (endT - startT) + "ms...");
			Thread.sleep((timeout-6) * 1000 - (endT - startT) + rand.nextInt(500));
			startT = System.currentTimeMillis();
			httpGet = new HttpGet(
					"http://www.pceggs.com/play/pg28mode.aspx?refresh=" + (lid));
			httpGet.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
			//get the odds...
			httpGet.addHeader("X_REQUESTED_WITH", "XMLHttpRequest");
			httpGet.addHeader("Referer", gambleURL);
			httpResponse = httpClient.execute(httpGet);
			odds = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
			i = 0;
			for (String value : odds.split(",")) {
				oddsList[i] = Double.parseDouble(value);
				System.out.print(oddsList[i] + ", ");
				i++;
			}
			System.out.println();
			httpGet.releaseConnection();
			endT = System.currentTimeMillis();
			System.out.println("Time: " + (endT - startT) + "ms...");
			
//          int[] finalDist = {1, 1, 10, 15, 24, 52, 87, 160, 200, 401, 515, 555, 601, 656, 656, 601, 555, 515, 401, 200, 160, 87, 52, 24, 15, 10, 1, 1};
//          int[] finalDist = {1, 3, 4, 7, 16, 32, 47, 123, 154, 290, 373, 402, 435, 475, 475, 435, 402, 373, 290, 154, 123, 47, 32, 16, 7, 4, 3, 1};
//          int[] finalDist = {1, 1, 1, 19, 29, 52, 87, 159, 199, 399, 512, 552, 598, 652, 652, 598, 552, 512, 399, 199, 159, 87, 52, 29, 19, 1, 1, 1};
//          int[] finalDist = {1, 1, 1, 24, 37, 45, 33, 39, 49, 198, 255, 274, 297, 324, 324, 297, 274, 255, 198, 49, 39, 33, 45, 37, 24, 1, 1, 1};
//			int[] finalDist = {1, 1, 1, 4, 8, 10, 16, 39, 49, 160, 205, 220, 239, 260, 260, 239, 220, 205, 160, 49, 39, 16, 10, 8, 4, 1, 1, 1};
//			int[] finalDist = {1, 1, 1, 1, 2, 3, 4, 5, 132, 147, 226, 244, 264, 288, 288, 264, 244, 226, 147, 132, 5, 4, 3, 2, 1, 1, 1, 1};
//			int[] finalDist = {0, 0, 0, 0, 0, 0, 0, 0, 48, 59, 66, 70, 77, 81, 81, 77, 70, 66, 59, 48, 0, 0, 0, 0, 0, 0, 0, 0};
//			int[] altFinalDist = {1, 4, 9, 14, 22, 26, 44, 53, 54, 60, 22, 24, 26, 28, 28, 26, 24, 22, 60, 54, 53, 44, 26, 22, 14, 9, 4, 1};
			int[] finalDist = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
			
//			totalWin = (int) (totalWin + lastTimes * (finalDist[history[0]] * oddsList[history[0]] - sum(finalDist)));
//			System.out.println("Win: " + (int) (lastTimes * (finalDist[history[0]] * oddsList[history[0]] - sum(finalDist))));
//			System.out.println("Total win: " + totalWin);
			
//			if(loseCount == 0) {
//				for(int j = 0; j < distMask.length; j++) {
//					distMask[j] = 1;
//				}
//				distMask[8] = distMask[9] = distMask[18] = distMask[19] = 0;
//			}
//			else if(history[0] <= 13) {
//				for(int j = 0; j < distMask.length; j++) {
//					if(j < 9)
//						distMask[j] = 0;
//					else
//						distMask[j] = 1;
//				}
//			}
//			else {
//				for(int j = 0; j < distMask.length; j++) {
//					if(j > 18)
//						distMask[j] = 0;
//					else
//						distMask[j] = 1;
//				}
//			}
			
			double sumFinal = 0;
			double[] invertOdds = new double[28];
			for(i = 0; i <= 27; i++) {
				if(distMask[i] > 0) {
					invertOdds[i] = 1 / oddsList[i];
					sumFinal = sumFinal + invertOdds[i];
				}
			}
			for(i = 0; i <= 27; i++) {
				if (distMask[i] > 0) {
					finalDist[i] = (int) Math.round(total * times / sumFinal * invertOdds[i]);
				}
			}

			httpPost = new HttpPost(
					"http://www.pceggs.com/play/pg28InsertDo.aspx");
			httpPost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
			List<NameValuePair> gambleParams = new ArrayList<NameValuePair>();
			String temps = String.valueOf(finalDist[0]);
			int s = finalDist[0];
			for (i = 1; i < 28; i++) {
				temps = temps + "," + finalDist[i];
				gambleParams.add(new BasicNameValuePair("SMONEY", String
						.valueOf(finalDist[i])));
				s += finalDist[i];
			}
			gambleParams.add(new BasicNameValuePair("ALLSMONEY", temps));
			Date date = new Date();
			date.setMinutes((date.getMinutes() / 5 + 1) * 5);
			gambleParams.add(new BasicNameValuePair("CTIME", df.format(date)));
			gambleParams.add(new BasicNameValuePair("Cheat", "CAE"));
			gambleParams
					.add(new BasicNameValuePair("LID", String.valueOf(lid)));
			gambleParams.add(new BasicNameValuePair("SMONEYSUM", String
					.valueOf(s)));
			gambleParams.add(new BasicNameValuePair("SMONEYY", "ALD"));
			gambleParams.add(new BasicNameValuePair("_issue", String
					.valueOf(gambleId)));
			gambleParams.add(new BasicNameValuePair("isdb_p", "0"));
			gambleParams.add(new BasicNameValuePair("lastgain", ""));
			httpPost.setEntity(new UrlEncodedFormEntity(gambleParams,
					HTTP.UTF_8));
			httpPost.addHeader("Host", "www.pceggs.com");
			httpPost.addHeader("Referer", gambleURL);
			httpPost.addHeader("User-Agent",
					"Mozilla/5.0 (Windows NT 6.1; rv:18.0) Gecko/20100101 Firefox/18.0");
			if(!watch) {
				httpResponse = httpClient.execute(httpPost);
				html = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
				httpPost.releaseConnection();
			}

			showStatus(oddsList, finalDist, 0, true);
			System.out.println("Current ID: " + gambleId);
			System.out.println();

			if(loseCount >= 3) {
				FileWriter fw1 = new FileWriter("Warning2.log", true);
				fw1.write("Current ID: " + gambleId + "\n");
				fw1.write(df.format(new Date()) + "\n");
				fw1.write("Warning!!!\n");
				fw1.write("LoseCount: " + loseCount);
				fw1.write("\n\n");
				fw1.close();
			}
			
			Thread.sleep(50000);

		}

	}
}